﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UFSSServerClasses;
using UFSSClientClasses;
using System.Collections;
using TestConsole.UFSSservicereference;


namespace TestConsole
{
    class Program
    {
       
        private static UFSSservicereference.UserCreds ucreds;
        private static UFSSservicereference.UserCreds ucreds2;
        private static ArrayList filelist = new ArrayList();
        private static ArrayList sublist = new ArrayList();
        private static ArrayList messlist = new ArrayList();
        private static List<string> friendlist = new List<string>();
        private static List<string> requestlist = new List<string>();
        private static int failtests = 0;
        private static int passtests = 0;
        private static UFSSservicereference.UFSSserviceSoapClient ssc = new UFSSservicereference.UFSSserviceSoapClient();
        
        static void Main(string[] args)
        {
           
            Console.SetWindowSize(Console.WindowWidth, Console.WindowHeight*2);
            ucreds = new UFSSservicereference.UserCreds();
            ucreds2 = new UFSSservicereference.UserCreds();
            Console.WriteLine("Testing has started!\n");
            
            
            //<tests>
            testWebService();
            testClasses();
            testDatabase();
            //</tests>
            testResults();
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Press enter for system information");
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.ReadLine();
            Console.Clear();
            dbStats();
            Console.ReadLine();

        }
        static void testWebService()
        {
           

            Console.WriteLine("--Web service testing started.");
            printTestResult("Service connection", (ssc.State == System.ServiceModel.CommunicationState.Created));
            Console.WriteLine("\tTesting webmethods:");
            ucreds.Username = "mattuser";
            ucreds.Password = "pass";
            ucreds2.Username = "robuser";
            ucreds2.Password = "pass";
            printTestResult("Failing authentication 1/2", !(ssc.ValidateToken(ucreds)));
            printTestResult("Login 1/4",ssc.LoginUser(ref ucreds));
            printTestResult("Login 2/4", ssc.LoginUser(ref ucreds2));
            printTestResult("Login 3/4",(ucreds.Token!=null));
            printTestResult("Login 4/4", (ucreds2.Token != null));
            //printTestResult("Upload file",(ssc.UploadFile(
            printTestResult("Successful authentication", (ssc.ValidateToken(ucreds)));
            byte[] file = null;
            printTestResult("Download file", (ssc.DownloadFile(ucreds, 40, ref file)));
            //FileReceiver fr;
            //fr = new FileReceiver("Testfile.jpg", file);
            //printTestResult(" --Write file (C:\\ufss\\)", fr.WriteFile("TEST"));
            printTestResult("Logout", (ssc.LogoutUser(ref ucreds)));
            printTestResult("Failing authenticaiton 2/2", !(ssc.ValidateToken(ucreds)));
            //printTestResult("Delete File", ssc.delFile(ucreds2, ));
            printTestResult("Add User", ssc.CreateUser("fname", "lname", "username", "pass", "email@email.com"));
            printTestResult("Delete User", ssc.DelUser("username"));
            printTestResult("Add Subscription", ssc.createSub(ucreds2, "public", "Super-De-Duper Subscription"));
            printTestResult("Join Subscription", ssc.joinSubscriptin(ucreds2, "Super-De-Duper Subscription"));
            printTestResult("Leave Subscription", ssc.leaveSubscription(ucreds2, "Super-De-Duper Subscription"));
            printTestResult("Delete Subscription", ssc.deleteSub(ucreds2, "Super-De-Duper Subscription"));
            printTestResult("Send Message", ssc.sendMessage(ucreds2, "mattuser", "message content", "subject"));
            printTestResult("Delete Message", ssc.delMessage(ucreds2, -1));
            printTestResult("Request Friend", ssc.addFriend(ucreds2, "unittestguy1"));
            printTestResult("Accept Friend", ssc.acceptFriend(ucreds2, "unittestguy1"));
            printTestResult("Reject Friend", ssc.rejectFriend(ucreds2, "unittestguy1"));
            
            UFSSservicereference.UFSSFile[] tempfile;
            ArrayOfString tempusername;
            UFSSservicereference.UFSSSubscription[] tempsub;

            tempfile = ssc.searchFiles(ucreds2, "");
            printTestResult("Search Files", (tempfile!= null));          
            tempusername = ssc.searchUsers(ucreds2, "");
            printTestResult("Search Users", (tempusername != null));            
            tempsub = ssc.searchSubs(ucreds2, "");
            printTestResult("Search Subs", (tempsub != null));

            tempfile = null;
            tempusername = null;
            tempsub = null;

            printTestResult("Get pop files", (ssc.getTopFiles(ucreds2, 5)) != null);
            printTestResult("Get pop users", (ssc.getTopUsers(ucreds2, 5)) != null);
            printTestResult("Get pop subs", (ssc.getTopSubs(ucreds2, 5)) != null);
            printTestResult("Get updates", (ssc.getFilesByDate(ucreds2, DateTime.Now.AddDays(-365), DateTime.Now)) != null);
            printTestResult("Friend-check", (ssc.isFriend(ucreds2, "mattuser")));
            printTestResult("Subscribed-check", (ssc.isSubbed(ucreds2, "sub1")));

            UFSSservicereference.UFSSFile[] fl = ssc.getFiles(ucreds);
            fl = ssc.getFiles(ucreds2);
            printTestResult("Get Files", !(fl == null));

            UFSSservicereference.UFSSSubscription[] sl = ssc.getSubs(ucreds);
            sl = ssc.getSubs(ucreds2);
            printTestResult("Get Subscriptions", !(sl == null));

            string[] friends = ssc.getFriends(ucreds2).ToArray();
            printTestResult("Get Friends", !(friends == null));

            string[] requests = ssc.getRequestedFriends(ucreds2).ToArray();
            printTestResult("Requested Friends", !(requests == null));

            UFSSservicereference.UFSSMessage[] ml = ssc.getMessages(ucreds);
            ml = ssc.getMessages(ucreds2);
            printTestResult("Get Messages", !(ml == null));

            Console.WriteLine("--Web service testing ended.");
        }
        static void testClasses()
        {
            Console.WriteLine("--Class testing started.");

            Console.WriteLine("\tTesting TokenHandler:");
            string token1 = TokenHandler.AddToken(1);
            string token2 = null;
            printTestResult("Intial token write",token1!=null);
            token2 = TokenHandler.AddToken(1);
            printTestResult("Token overwrite",((token2!=null)&&(token1!=token2)));
            printTestResult("Token removal", (TokenHandler.RemoveToken(token2)));
            Console.WriteLine("--Class testing ended.");
        }
        static void testDatabase()
        {
            Console.WriteLine("--Database testing started.");
 

            Console.WriteLine("\tTesting Stored Procedures:");
            Console.WriteLine("\t\tUploading and downloading may take a while... (5mb)");
            string uphash = (FileAccess.uploadFile(0, System.IO.File.ReadAllBytes("test.jpg"), "Huge File"));
            printTestResult("Upload file",uphash!=null);
            Console.WriteLine("Upload hash: " + uphash);
            printTestResult("Get filesize", (FileAccess.getFileSize(40) >= 0));
            byte[] downbytes = (FileAccess.downloadFile(40, 1));
            printTestResult("Download file", downbytes  != null);
            string originalhash = FileAccess.getHash(System.IO.File.ReadAllBytes("test.jpg"));
            printTestResult("MD5", (originalhash != null));
            Console.WriteLine("Original hash: " + originalhash);
            printTestResult("File integrity", uphash.Equals(originalhash));
            printTestResult("Delete file",(FileAccess.deleteFile(-1, DBAccess.getUserID(ucreds2.Username))));
            printTestResult("Delete file fail", (FileAccess.deleteFile(-1, 99999)));
            printTestResult("User login",UserAccess.login("mattuser", "pass") != null);
            printTestResult("Get user info",UserAccess.getUserInfo("mattuser") != null);
            printTestResult("Get userid",DBAccess.getUserID("mattuser") >= 0);
            printTestResult("Update user",UserAccess.updateUser("mattuser", "Matt", "Hague", "email@mail.ma"));
            printTestResult("Add User", UserAccess.addUser("testuser", "pass", "test", "User", "email@email", "9834"));
            printTestResult("Delete User", UserAccess.deluser("testuser"));
            printTestResult("Request Friend", FriendAccess.requestFriend("unittestguy1", "unittestguy2"));
            printTestResult("Accept Friend", FriendAccess.addFriend("unittestguy2", "unittestguy1"));
            printTestResult("Send Message", FriendAccess.sendMessage("unittestguy1", "unittestguy2", "Hello", "Subject"));
            printTestResult("Reject Friend", FriendAccess.rejectFriend("unittestguy1", "unittestguy2"));
            printTestResult("Edit Message", FriendAccess.editMessage(-1, "edited message"));
            printTestResult("Delete Message", FriendAccess.delMessage(-1));
            printTestResult("Add Subscription", SubAccess.addSub("PUBLIC", "mattuser", "TestingName"));
            printTestResult("Join Subscription", SubAccess.joinSub("robuser", "TestingName"));
            printTestResult("Get ownerID", (SubAccess.getSubOwner(SubAccess.getSubID("a name")))>=0);
            printTestResult("Leave Subscription", SubAccess.leaveSub("robuser", "TestingName"));
            printTestResult("Delete Subscription", SubAccess.delSub("mattuser", "TestingName"));
            printTestResult("Get Subscription info", (SubAccess.getSubscriptionInfo(1)) != null);
            printTestResult("Get Top Users", (UserAccess.getTopUsers(5)) != null);
            printTestResult("Get Top Files", (FileAccess.getTopFiles(5)) != null);
            printTestResult("Get Top Subs", (SubAccess.getTopSubs(5)) != null);
            printTestResult("Reset Password",(UserAccess.forgotPass("robuser", "email@mail.com")) != null);
            printTestResult("Update Password", (UserAccess.updatePass(0, "pass")));
            printTestResult("Search Users", UserAccess.searchUsers("mattuser")!=null);
            printTestResult("Search Files", FileAccess.searchFiles("Test") != null);
            printTestResult("Search Subs", SubAccess.searchSubs("sub") != null);
            printTestResult("Files by date", FileAccess.getFilesByDate(DateTime.Now.AddDays(-365), DateTime.Now)!=null);
            
            
            filelist = FileAccess.getFiles(1);
            printTestResult("Get Files", !(filelist == null));

            sublist = SubAccess.getSubscription(0);
            printTestResult("Get Subscriptions", !(sublist == null));

            friendlist = FriendAccess.getFriends(0);
            printTestResult("Get Friends", !(friendlist.Count() == 0));

            requestlist = FriendAccess.getRequestedFriends(0);
            printTestResult("Requested Friends", !(requestlist.Count() == 0));

            messlist = FriendAccess.getMessage(0);
            printTestResult("Get Messages", !(messlist == null));

            Console.WriteLine("--Database testing ended.");
        }
        static void dbStats()
        {
            Dictionary<string,long> stats = new Dictionary<string,long>();
            stats = SystemAccess.getSystemStats();
            double storagelimit =(stats["StorageBytesLimit"]);
            double storageused = (stats["StorageBytesValue"]);
            double userstoragelimit = (stats["UserStorageBytesLimit"]);
            double userfilelimit = (stats["UserFileLimit"]);
            double usersublimit = (stats["UserSubLimit"]);
            Console.WriteLine("=======================System Statistics=========================\n");
            printInformation("Storage used", storageused.ToString()," bytes");
            printInformation("Storage limit", storagelimit.ToString()," bytes");
            printInformation("Storage remaining", (1-(storageused/storagelimit)).ToString("P"),null);
            printInformation("Per-user storage limit", userstoragelimit.ToString(), " bytes");
            printInformation("Per-user file limit", userfilelimit.ToString(), " files");
            printInformation("Per-user subscription limit", usersublimit.ToString(), " subs");

        }
        public static void printInformation(string caption, string value, string unit)
        {
            for (int i = 0; i < (35 - (caption.Length)); i++)
                Console.Write(" ");
            Console.Write(caption + ":\t\t");
            Console.ForegroundColor = ConsoleColor.White;
            Console.Write(value+" "+unit);
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.Write("\n");
        }
        public static void printTestResult(string caption, bool isSuccessful)
        {
            for (int i = 0; i < (50 -(caption.Length)); i++)
                Console.Write(" ");
            Console.Write(caption + ":\t\t");
            if(isSuccessful)
            {
                passtests += 1;
                Console.ForegroundColor = ConsoleColor.Green;
                Console.Write("SUCCESS\n");
            }
            else
            {
                failtests += 1;
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write("FAIL\n");
            }
                Console.ForegroundColor = ConsoleColor.Gray;

        }
        static void testResults()
        {
            if(failtests==0)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("All " + passtests.ToString() + " tests have passed!");
                Console.ForegroundColor = ConsoleColor.Gray;
                return;
            }
            Console.ForegroundColor = ConsoleColor.Red;
            Console.Write("Tests failed: " + failtests.ToString());
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("       Tests passed: " + passtests.ToString());
            Console.ForegroundColor = ConsoleColor.Gray;
        }
    }

}
